home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Leser 15 / Amiga Plus Leser CD 15.iso / Tools / Development / mmu / MuManual / C_Sources / MuFastChip.c < prev    next >
C/C++ Source or Header  |  2002-03-12  |  14KB  |  383 lines

  1. /*****************************************************************
  2.  ** MuFastChip                                                  **
  3.  **                                                             **
  4.  ** Enable imprecise/nonserial flags for Chip memory            **
  5.  ** Release 40.3, © 1999,2001 THOR-Software inc.                **
  6.  ** 28.04.2001 Thomas Richter                                   **
  7.  *****************************************************************/
  8.  
  9. /// Includes
  10. #include <exec/types.h>
  11. #include <exec/memory.h>
  12. #include <exec/ports.h>
  13. #include <exec/execbase.h>
  14. #include <dos/dos.h>
  15. #include <mmu/mmubase.h>
  16. #include <mmu/context.h>
  17. #include <mmu/mmutags.h>
  18. #include <workbench/startup.h>
  19.  
  20. #include <thor/conversions.h>
  21.  
  22. #include <proto/exec.h>
  23. #include <proto/mmu.h>
  24. #include <proto/dos.h>
  25. #include <proto/icon.h>
  26. #include <string.h>
  27. ///
  28. /// Defines
  29. #define STRINGDATE "28.4.2001"
  30. #define STRINGVERSION "40.3"
  31. #define TEMPLATE "ON/S,OFF/S"
  32.  
  33. #define OPT_ON 0
  34. #define OPT_OFF 1
  35. #define OPT_WINDOW 2
  36. #define OPT_COUNT 3
  37. ///
  38. /// Statics
  39. struct MMUBase *MMUBase;
  40. struct DosLibrary *DOSBase;
  41. struct ExecBase *SysBase;
  42. struct Library *IconBase;
  43. ///
  44. /// Protos
  45. int __asm __saveds main(void);
  46. int SetCacheMode(ULONG from,ULONG size,ULONG flags,ULONG mask);
  47. struct RDArgs *ReadTTArgs(struct WBStartup *msg,LONG args[],struct RDArgs **tmp);
  48. int DisableFastChip(void);
  49. int EnableFastChip(void);
  50. BOOL FindChipLimits(ULONG *from,ULONG *size);
  51. ULONG FindProperties(ULONG address);
  52. ///
  53.  
  54. char version[]="$VER: MuFastChip " STRINGVERSION " (" STRINGDATE ") © THOR";
  55.  
  56. /// main
  57. int __asm __saveds main(void)
  58. {
  59. LONG args[OPT_COUNT];
  60. struct RDArgs *rd,*myrd;
  61. struct Process *proc;
  62. int rc=20;
  63. LONG err;
  64. struct WBStartup *msg;
  65. BPTR oldout;
  66. struct MsgPort *oldconsole;
  67.  
  68.         SysBase=*((struct ExecBase **)(4L));
  69.  
  70.         memset(args,0,sizeof(LONG)*OPT_COUNT);
  71.  
  72.         /* Wait for the workbench startup, if any */
  73.         proc=(struct Process *)FindTask(NULL);
  74.  
  75.         if (!(proc->pr_CLI)) {
  76.                 WaitPort(&(proc->pr_MsgPort));
  77.                 msg=(struct WBStartup *)GetMsg(&(proc->pr_MsgPort));
  78.         } else  msg=NULL;
  79.  
  80.         if (DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",37L)) {
  81.                 if (MMUBase=(struct MMUBase *)OpenLibrary("mmu.library",41L)) {
  82.  
  83.                         err=ERROR_REQUIRED_ARG_MISSING;
  84.  
  85.                         myrd=NULL;      /* reset the temporary ReadArgs */
  86.                         oldout=NULL;
  87.                         oldconsole=NULL;
  88.                         if (msg) {
  89.                                 oldout=SelectOutput(NULL);
  90.                                 oldconsole=SetConsoleTask(NULL);
  91.                                 rd=ReadTTArgs(msg,args,&myrd);
  92.                         } else  rd=ReadArgs(TEMPLATE,args,NULL);
  93.  
  94.                         if (rd) {
  95.                                 if (!GetMMUType()) {
  96.                                         Printf("MuFastChip requires a working MMU.\n");
  97.                                         err=10;
  98.                                 } else {
  99.  
  100.                                         err=0;
  101.  
  102.                                         if (args[OPT_ON] || (!args[OPT_OFF])) {
  103.                                                 err=EnableFastChip();
  104.                                         }
  105.  
  106.                                         if (args[OPT_OFF]) {
  107.                                                 err=DisableFastChip();
  108.                                         }
  109.                                 }
  110.  
  111.                                 FreeArgs(rd);
  112.                                 if (myrd) FreeDosObject(DOS_RDARGS,myrd);
  113.                                 if (msg)  Close(SelectOutput(NULL));
  114.                         } else  err=IoErr();
  115.  
  116.                         if (msg) {
  117.                                 SelectOutput(oldout);
  118.                                 SetConsoleTask(oldconsole);
  119.                         }
  120.  
  121.                         if (err<64) {
  122.                                 rc=err;
  123.                                 err=0;
  124.                         } else {
  125.                                 if (!msg) PrintFault(err,"MuFastChip failed");
  126.                                 rc=10;
  127.                         }
  128.                         SetIoErr(err);
  129.  
  130.                         CloseLibrary((struct Library *)MMUBase);
  131.                 } else if (!msg) PrintFault(ERROR_OBJECT_NOT_FOUND,"MuFastChip requires the mmu.library V41 or better");
  132.                 CloseLibrary((struct Library *)DOSBase);
  133.         }
  134.  
  135.         if (msg) {
  136.                 Forbid();
  137.                 ReplyMsg((struct Message *)msg);
  138.         }
  139.  
  140.         return rc;
  141. }
  142. ///
  143. /// ReadTTArgs
  144. struct RDArgs *ReadTTArgs(struct WBStartup *msg,LONG args[],struct RDArgs **tmp)
  145. {
  146. struct WBArg *wbarg;
  147. struct DiskObject *dop;
  148. char **tt;                      /* ToolTypes array */
  149. char *wbstr;                    /* Our self-made workbench argument string */
  150. char *here;
  151. BPTR oldlock;
  152. ULONG len;
  153. struct RDArgs *rd=NULL,*myrd=NULL;
  154. LONG err=0;
  155. BPTR newout;
  156.  
  157.         if (IconBase=OpenLibrary("icon.library",37L)) {
  158.                 if (wbarg=msg->sm_ArgList) {
  159.                         /* use a project icon if there is one... */
  160.                         if (msg->sm_NumArgs > 1) wbarg++;
  161.  
  162.                         /* go into the directory */
  163.                         oldlock=CurrentDir(wbarg->wa_Lock);
  164.  
  165.                         if (dop=GetDiskObject(wbarg->wa_Name)) {
  166.                                 if (tt=dop->do_ToolTypes) {
  167.                                         /* Read a special tool type for the output window */
  168.  
  169.                                         /* Calc the size of the argument string */
  170.  
  171.                                         len = 3;        /* reserve space for SPC,LF,NUL */
  172.                                         while (*tt) {
  173.                                                 len += strlen(*tt)+1;   /* string, plus space */
  174.                                                 tt++;
  175.                                         }
  176.  
  177.                                         if (wbstr=AllocVec(len,MEMF_PUBLIC)) {
  178.                                                 /* Now copy the arguments into this string, one by one
  179.                                                    and check whether the argument string is still valid. */
  180.  
  181.                                                 tt=dop->do_ToolTypes;
  182.                                                 here=wbstr;
  183.                                                 do{
  184.                                                         *here='\0';                     /* terminate string */
  185.                                                         /* Check whether this tool type is
  186.                                                            commented out. Just ignore it in this case */
  187.                                                         if (*tt) {
  188.                                                                 if (**tt=='(' || **tt==';')
  189.                                                                         continue;
  190.  
  191.                                                                 strcpy(here,*tt);      /* Add TT string */
  192.                                                         }
  193.                                                         len=strlen(here);
  194.                                                         here[len]='\n';
  195.                                                         here[len+1]='\0';               /* terminate string */
  196.  
  197.                                                         /* Now try to ReadArg' this string */
  198.  
  199.                                                         /* release old arguments left over from last loop */
  200.                                                         if (rd) FreeArgs(rd);
  201.                                                         if (myrd) FreeDosObject(DOS_RDARGS,myrd);
  202.                                                         rd=NULL;
  203.                                                         memset(args,0,sizeof(LONG)*OPT_COUNT);
  204.  
  205.                                                         if (myrd=AllocDosObject(DOS_RDARGS,NULL)) {
  206.                                                                 /* Allocate and setup the ReadArgs source */
  207.                                                                 myrd->RDA_Source.CS_Buffer=wbstr;
  208.                                                                 myrd->RDA_Source.CS_Length=strlen(wbstr);
  209.  
  210.                                                                 if (rd=ReadArgs(TEMPLATE ",WINDOW/K",args,myrd)) {
  211.                                                                         /* Is this still valid? */
  212.                                                                         here[len]=' ';
  213.                                                                         here+=len+1;
  214.                                                                         /* if so, accept this argument and go on */
  215.                                                                 } else {
  216.                                                                         err=IoErr();
  217.                                                                         if (err==ERROR_NO_FREE_STORE) break;
  218.                                                                         else    err=0;  /* Ignore unknown or invalid arguments silently */
  219.                                                                 }
  220.                                                         } else {
  221.                                                                 err=ERROR_NO_FREE_STORE;
  222.                                                                 break;
  223.                                                         }
  224.                                                 }while(*tt++);
  225.  
  226.                                                 FreeVec(wbstr);
  227.                                         } else err=ERROR_NO_FREE_STORE;
  228.                                 } else err=ERROR_REQUIRED_ARG_MISSING; /* Huh, how should this happen ? */
  229.                                 FreeDiskObject(dop);
  230.                         } else err=IoErr();
  231.                         CurrentDir(oldlock);
  232.                 } else err=ERROR_REQUIRED_ARG_MISSING; /* This should not happen either */
  233.                 CloseLibrary(IconBase);
  234.         } else err=ERROR_OBJECT_NOT_FOUND;    /* This should not happen */
  235.  
  236.         /* Open an output stream */
  237.  
  238.         if (err==0) {
  239.                 if (newout=Open((args[OPT_WINDOW])?((char *)args[OPT_WINDOW]):("NIL:"),MODE_NEWFILE)) {
  240.                         SelectOutput(newout);
  241.                         /* Hack in the output console. Well, well... */
  242.                         SetConsoleTask(((struct FileHandle *)(BADDR(newout)))->fh_Type);
  243.                 } else err=IoErr();
  244.         }
  245.  
  246.         if (err) {
  247.                 if (rd)   FreeArgs(rd);
  248.                 if (myrd) FreeDosObject(DOS_RDARGS,myrd);
  249.                 SetIoErr(err);
  250.                 rd=NULL;
  251.                 myrd=NULL;
  252.         }
  253.  
  254.         *tmp=myrd;
  255.         return rd;
  256. }
  257. ///
  258. /// EnableFastChip
  259. int EnableFastChip(void)
  260. {
  261. ULONG from,size;
  262.  
  263.         if (FindChipLimits(&from,&size)) {
  264.                 if ((FindProperties(from) & (MAPP_IMPRECISE|MAPP_NONSERIALIZED)) == (MAPP_IMPRECISE|MAPP_NONSERIALIZED)) {
  265.                         Printf("The chip memory caching mode is already optimal.\n"
  266.                                "MuFastChip is not required.\n");
  267.                         return 5;
  268.                 }
  269.                 return SetCacheMode(from,size,MAPP_IMPRECISE|MAPP_NONSERIALIZED,MAPP_IMPRECISE|MAPP_NONSERIALIZED);
  270.         } else  return 20;
  271.  
  272. }
  273. ///
  274. /// DisableFastChip
  275. int DisableFastChip(void)
  276. {
  277. ULONG from,size;
  278.  
  279.         if (FindChipLimits(&from,&size)) {
  280.                 if ((FindProperties(from) & (MAPP_IMPRECISE|MAPP_NONSERIALIZED)) == 0) {
  281.                         Printf("MuFastChip is not activated.\n");
  282.                         return 5;
  283.                 }
  284.                 return SetCacheMode(from,size,0,MAPP_IMPRECISE|MAPP_NONSERIALIZED);
  285.         } else  return 20;
  286.  
  287. }
  288. ///
  289. /// FindProperties
  290. ULONG FindProperties(ULONG address)
  291. {
  292.         return GetProperties(DefaultContext(),address,TAG_DONE);
  293. }
  294. ///
  295. /// FindChipLimits
  296. BOOL FindChipLimits(ULONG *from,ULONG *size)
  297. {
  298. struct MMUContext *ctx;
  299. ULONG psize;
  300. ULONG upper,lower;
  301. struct MemHeader *memh;
  302.  
  303.         ctx=DefaultContext();
  304.         psize=GetPageSize(ctx);
  305.         lower=0xffffffff;
  306.         upper=0;
  307.         Forbid();
  308.         for(memh=(struct MemHeader *)SysBase->MemList.lh_Head;
  309.             memh->mh_Node.ln_Succ;
  310.             memh=(struct MemHeader *)memh->mh_Node.ln_Succ) {
  311.  
  312.                 if (memh->mh_Attributes & MEMF_CHIP) {
  313.                         if ((ULONG)(memh->mh_Lower) < lower) {
  314.                                 lower=(ULONG)(memh->mh_Lower);
  315.                         }
  316.                         if ((ULONG)(memh->mh_Upper) > upper) {
  317.                                 upper=(ULONG)(memh->mh_Upper);
  318.                         }
  319.                 }
  320.         }
  321.         Permit();
  322.  
  323.         if (lower>=upper) {
  324.                 Printf("MuFastChip failed: no MEMF_CHIP memory found.\n");
  325.                 return FALSE;
  326.         }
  327.  
  328.         upper += psize-1;
  329.         lower &= -psize;
  330.         upper &= -psize;
  331.  
  332.  
  333.         *from=lower;
  334.         *size=upper-lower;
  335.  
  336.         return TRUE;
  337. }
  338. ///
  339. /// SetCacheMode
  340. int SetCacheMode(ULONG from,ULONG size,ULONG flags,ULONG mask)
  341. {
  342. struct MMUContext *ctx,*sctx;   /* default context, supervisorcontext */
  343. struct MinList *ctxl,*sctxl;
  344. int err;
  345.  
  346.         ctx=DefaultContext();   /* get the default context */
  347.         sctx=SuperContext(ctx); /* get the supervisor context for this one */
  348.  
  349.         LockContextList();
  350.         LockMMUContext(ctx);
  351.         LockMMUContext(sctx);
  352.  
  353.         err=ERROR_NO_FREE_STORE;
  354.  
  355.         if (ctxl=GetMapping(ctx)) {
  356.          if (sctxl=GetMapping(sctx)) {
  357.           if (SetProperties(ctx,flags,mask,from,size,TAG_DONE)) {
  358.            if (SetProperties(sctx,flags,mask,from,size,TAG_DONE)) {
  359.             if (RebuildTrees(ctx,sctx,NULL)) {
  360.                     err=0;
  361.             }
  362.            }
  363.           }
  364.  
  365.           if (err) {
  366.                   SetPropertyList(ctx,ctxl);
  367.                   SetPropertyList(sctx,sctxl);
  368.           }
  369.  
  370.          ReleaseMapping(sctx,sctxl);
  371.          }
  372.         ReleaseMapping(ctx,ctxl);
  373.         }
  374.  
  375.         UnlockMMUContext(sctx);
  376.         UnlockMMUContext(ctx);
  377.         UnlockContextList();
  378.  
  379.         return err;
  380. }
  381. ///
  382.  
  383.